home *** CD-ROM | disk | FTP | other *** search
- (*===========================================================================*)
- (* Procedure for initializing messages *)
- (* *)
- (* Copyright 1988, 1989, 1990, 1991 by H. Roy Engehausen. All rights *)
- (* reserved. *)
- (* *)
- (*===========================================================================*)
-
- {$DEFINE POINT_CHK}
- {$DEFINE FREE_CHK}
- {$UNDEF DEBUG_L1} (* Debug language area 1 -- File names *)
- {$UNDEF DEBUG_2} (* Debug error handling *)
-
- {$O+} {This procedure gets overlayed}
-
- UNIT BBMINIT;
-
- INTERFACE
-
- PROCEDURE message_init(error_abort : BOOLEAN);
- PROCEDURE message_reload;
-
- IMPLEMENTATION
-
- USES
- CRT,
- bbdummy,
- bbmdata,
- bbmess,
- bbmisc2,
- bbmisc3,
- bbsdata,
- bbsema2,
- bbstr,
- bbtask,
- bbtime,
- bbwin;
-
- (*===========================================================================*)
- (* Add message queue -- Add something to the message queue *)
- (*===========================================================================*)
-
- PROCEDURE add_message_q(VAR message_q : qe_ptr;
- file_qe : BOOLEAN;
- data_qe : string);
-
- VAR
- i : WORD;
- old_qe : qe_ptr;
- work_qe : qe_ptr;
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* Build a queue element with the data in it. *)
- (*-----------------------------------------------------------------------*)
-
- i := WORD(qe_overhead) + LENGTH(data_qe);
-
- GETMEM(work_qe, i);
-
- WITH work_qe^ DO
- BEGIN;
- qe_next := NIL;
- qe_file_type := file_qe;
- i := 1 + LENGTH(data_qe);
- MOVE(data_qe, qe_data, i);
- END;
-
- (*-----------------------------------------------------------------------*)
- (* If the head of the queue is empty, hang it on the head else *)
- (* hang it off the tail *)
- (*-----------------------------------------------------------------------*)
-
- IF message_q = NIL THEN
- message_q := work_qe
- ELSE
- BEGIN;
-
- old_qe := message_q;
-
- WHILE old_qe^.qe_next <> NIL DO
- BEGIN;
-
- {$IFDEF POINT_CHK}
- test_pointer(old_qe);
- {$ENDIF}
-
- old_qe := old_qe^.qe_next;
-
- END;
-
- old_qe^.qe_next := work_qe;
-
- END;
-
- END;
-
- (*===========================================================================*)
- (* Message init *)
- (*===========================================================================*)
-
- PROCEDURE message_init(error_abort : BOOLEAN);
-
- VAR
- error_sw : BOOLEAN;
- i : BYTE;
- j : user_class_type;
- code : INTEGER;
- line_cnt : WORD;
- message_no : INTEGER;
-
- (*=========================================================================*)
- (* Sub procedure to send error messages *)
- (*=========================================================================*)
-
- PROCEDURE send_err_mess(mess : STRING);
- BEGIN;
-
- {$IFDEF DEBUG_2}
- WRITELN('Error handler -- ', mess);
- test_pointer(active_tcb);
- WRITELN('TCB type -- ', ORD(active_tcb^.tcb_type));
- {$ENDIF}
-
- IF active_tcb^.tcb_type = th_main THEN
- WRITELN(mess)
- ELSE
- send_tnc_data_str(mess + cr);
- active_tcb^.error_sw := TRUE;
- error_sw := TRUE;
- END;
-
- (*=========================================================================*)
- (* Sub procedure to process one message file *)
- (*=========================================================================*)
-
- PROCEDURE message_file_process(lang_char : CHAR; lang_num : BYTE);
-
- VAR
- i : BYTE;
- in_str : STRING;
- mess_file : TEXT;
- mess_head : mess_list_ptr;
- mess_old : mess_list_ptr;
- mess_work : mess_list_ptr;
- s : STRING[5];
- uc : user_class_type;
-
- LABEL
- read_loop;
-
- BEGIN;
-
- (*---------------------------------------------------------------------*)
- (* Assign name *)
- (*---------------------------------------------------------------------*)
-
- in_str := opt_block.mess_fn + lang_char;
-
- ASSIGN(mess_file, in_str);
-
- (*---------------------------------------------------------------------*)
- (* Open *)
- (*---------------------------------------------------------------------*)
-
- {$I-}
- RESET(mess_file);
- {$I+}
- i := IORESULT;
-
- IF i <> 0 THEN
- BEGIN;
- STR(i, s);
- send_err_mess('**** MESSAGE FILE (' + in_str
- + ') not found -- Dos error = ' + s);
- EXIT;
- END;
-
- (*---------------------------------------------------------------------*)
- (* Get ready to process file *)
- (*---------------------------------------------------------------------*)
-
- error_sw := FALSE;
- line_cnt := 0;
- message_no := 0;
- mess_head := NIL;
-
- (*---------------------------------------------------------------------*)
- (* Loop thru file *)
- (*---------------------------------------------------------------------*)
-
- read_loop:
-
- WHILE NOT EOF(mess_file) DO
- BEGIN;
-
- (*-----------------------------------------------------------------*)
- (* Read a line and count it *)
- (*-----------------------------------------------------------------*)
-
- READLN(mess_file, in_str);
-
- line_cnt := line_cnt + 1;
-
- (*-----------------------------------------------------------------*)
- (* Skip blanks and comments *)
- (*-----------------------------------------------------------------*)
-
- IF in_str = '' THEN
- GOTO read_loop;
-
- code := 1;
- WHILE (code <= LENGTH(in_str)) DO
- CASE in_str[code] OF
- ';' : GOTO read_loop;
- ' ' : INC(code);
- ELSE
- code := 256;
- END;
-
- (*-----------------------------------------------------------------*)
- (* See it if is a header *)
- (*-----------------------------------------------------------------*)
-
- IF (LENGTH(in_str) > 2) AND (in_str[1] = ':') THEN
- BEGIN;
-
- (*-------------------------------------------------------------*)
- (* See it if is a header even more *)
- (*-------------------------------------------------------------*)
-
- IF (WORDS(in_str) = 3) AND (in_str[2] = ' ') THEN
- BEGIN;
-
- (*---------------------------------------------------------*)
- (* Process message number *)
- (*---------------------------------------------------------*)
-
- VAL(subword(@in_str, 2, 1), message_no, code);
-
- {$IFDEF DEBUG_2}
- WRITELN('Number text = ', subword(@in_str, 2, 1));
- WRITELN('Message number -- ', message_no, '/', code);
- {$ENDIF}
-
- IF (code <> 0) OR (message_no < 1) OR
- (message_no > max_message) THEN
- BEGIN;
- STR(line_cnt, s);
- send_err_mess(
- 'Error in message file -- Bad message # -- line # '
- + s);
- message_no := 0;
- GOTO read_loop;
- END;
-
- (*---------------------------------------------------------*)
- (* Process type *)
- (*---------------------------------------------------------*)
-
- in_str := subword(@in_str, 3, 1);
-
- IF LENGTH(in_str) <> 1 THEN
- BEGIN;
- STR(line_cnt, s);
- send_err_mess(
- 'Error in message file -- Bad user class -- line # '
- + s);
- GOTO read_loop;
- END;
-
- CASE UPCASE(in_str[1]) OF
- 'N' : uc := user_c_nu;
- 'U' : uc := user_c_uu;
- 'O' : uc := user_c_ou;
- 'E' : uc := user_c_eu;
- 'B' : uc := user_c_bu;
- 'R' : uc := user_c_rsu;
- 'L' : uc := user_c_lsu;
- ELSE
- BEGIN;
- STR(line_cnt, s);
- send_err_mess(
- 'Error in message file -- Bad user class -- line # '
- + s);
- GOTO read_loop;
- END;
- END;
-
- (*---------------------------------------------------------*)
- (* Allocate the message *)
- (*---------------------------------------------------------*)
-
- NEW(mess_head);
- WITH mess_head^ DO
- BEGIN;
- mess_next := NIL;
- mess_this := NIL;
- mess_lang := lang_num;
- mess_class := uc;
- END;
-
- (*---------------------------------------------------------*)
- (* Get head of chain *)
- (*---------------------------------------------------------*)
-
- mess_work := message_array[message_no];
-
- {$IFDEF POINT_CHK}
- IF mess_work <> NIL THEN
- test_pointer(mess_work);
- {$ENDIF}
-
- (*---------------------------------------------------------*)
- (* Look for insertion point *)
- (*---------------------------------------------------------*)
-
- IF (mess_work = NIL)
- OR (mess_work^.mess_class < uc)
- OR ((mess_work^.mess_class = uc)
- AND (mess_work^.mess_lang < lang_num)) THEN
- BEGIN;
-
- (*-----------------------------------------------------*)
- (* Insert at head of chain *)
- (*-----------------------------------------------------*)
-
- message_array[message_no] := mess_head;
- mess_head^.mess_next := mess_work;
- END
- ELSE
- BEGIN;
-
- (*-----------------------------------------------------*)
- (* Search chain for insertion point *)
- (*-----------------------------------------------------*)
-
- REPEAT
-
- {$IFDEF POINT_CHK}
- test_pointer(mess_work);
- {$ENDIF}
-
- mess_old := mess_work;
- mess_work := mess_work^.mess_next;
-
- {$IFDEF DEBUG_L1}
- IF message_no = 4 THEN
- BEGIN;
- WRITELN('Test -- ', ORD(mess_work^.mess_class),
- ' -- ', mess_work^.mess_lang);
- WRITELN(mess_work^.mess_class < uc, ' ',
- (mess_work^.mess_class = uc)
- AND (mess_work^.mess_lang > lang_num));
- DELAY(1000);
- END;
- {$ENDIF}
-
- UNTIL (mess_work = NIL)
- OR (mess_work^.mess_class < uc)
- OR ((mess_work^.mess_class = uc)
- AND (mess_work^.mess_lang < lang_num));
-
- IF (mess_work <> NIL)
- AND (mess_work^.mess_class = uc)
- AND (mess_work^.mess_lang = lang_num) THEN
- BEGIN;
- STR(line_cnt, s);
- send_err_mess(
- 'Error in message file -- Duplicate -- line # '
- + s);
- GOTO read_loop;
- END;
-
- {$IFDEF DEBUG_L1}
- IF message_no = 4 THEN
- BEGIN;
- WRITELN('Insert -- ', ORD(uc), ' -- ', lang_num);
- WRITELN('Before -- ', ORD(mess_work^.mess_class),
- ' -- ', mess_work^.mess_lang);
- WRITELN('After -- ', ORD(mess_old^.mess_class),
- ' -- ', mess_old^.mess_lang);
- END;
- {$ENDIF}
-
- mess_old^.mess_next := mess_head;
- mess_head^.mess_next := mess_work;
-
- END;
-
- END
- ELSE
- BEGIN;
-
- (*---------------------------------------------------------*)
- (* Bad header format *)
- (*---------------------------------------------------------*)
-
- STR(line_cnt, s);
- send_err_mess(
- 'Error in message file -- Bad header format -- line # '
- + s);
- GOTO read_loop;
-
- END;
- END
- ELSE
- BEGIN;
-
- (*-------------------------------------------------------------*)
- (* Add a text line to the message *)
- (*-------------------------------------------------------------*)
-
- IF message_no <> 0 THEN
- BEGIN
-
- strip_var(in_str, 'T');
-
- IF (LENGTH(in_str) = 1) AND (in_str[1] = '%') THEN
- in_str[1] := ' ';
-
- IF LENGTH(in_str) > 0 THEN
- IF in_str[1] <> '@' THEN
- add_message_q(mess_head^.mess_this, FALSE, in_str)
- ELSE
- add_message_q(mess_head^.mess_this,
- TRUE, SUBSTR(in_str, 2, 0));
-
- END;
-
- END;
- END;
-
- (*---------------------------------------------------------------------*)
- (* Close things up *)
- (*---------------------------------------------------------------------*)
-
- CLOSE(mess_file);
-
- END;
-
- (*=========================================================================*)
- (* Main line of message load *)
- (*=========================================================================*)
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* Initialize things *)
- (*-----------------------------------------------------------------------*)
-
- error_sw := FALSE;
-
- FOR i := 1 TO max_message DO
- message_array[i] := NIL;
-
- i := LENGTH(opt_block.language_list);
-
- WHILE (i > 1) AND (NOT error_sw) DO
- BEGIN;
-
- {$IFDEF DEBUG_L1}
- WRITELN('MFload -- ', i, '--', opt_block.language_list[i]);
- {$ENDIF}
-
- message_file_process(opt_block.language_list[i], i-1);
-
- DEC(i);
-
- END;
-
- IF NOT error_sw THEN
- message_file_process(' ', 0);
-
- (*-----------------------------------------------------------------------*)
- (* Abort on error *)
- (*-----------------------------------------------------------------------*)
-
- IF error_sw AND error_abort THEN
- BEGIN;
- WRITELN('Fatal error in message file loading');
- HALT;
- END;
-
- END;
-
- (*===========================================================================*)
- (* Reload message file *)
- (*===========================================================================*)
-
- PROCEDURE message_reload;
-
- VAR
- i : WORD;
- mess_inx : BYTE;
- next_mess : mess_list_ptr;
- next_qe : qe_ptr;
- work_mess : mess_list_ptr;
- work_qe : qe_ptr;
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* See if we can run. *)
- (*-----------------------------------------------------------------------*)
-
- IF bbs_busy THEN
- BEGIN;
- send_message(message_other_active);
- EXIT;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Obtain the interrupt lock *)
- (*-----------------------------------------------------------------------*)
-
- get_semaphore(semaphore_interrupts, sem_exclusive, FALSE);
-
- (*-----------------------------------------------------------------------*)
- (* Tell user started *)
- (*-----------------------------------------------------------------------*)
-
- window_write(active_tcb^.port_chan_s + '>:',
- 'Reload is started -- All tasks are locked. Please wait.');
-
- (*-----------------------------------------------------------------------*)
- (* Unload the message lists *)
- (*-----------------------------------------------------------------------*)
-
- FOR mess_inx := 1 TO max_message DO
- BEGIN;
- next_mess := message_array[mess_inx];
- WHILE next_mess <> NIL DO
- BEGIN;
-
- {$IFDEF POINT_CHK}
- test_pointer(next_mess);
- {$ENDIF}
-
- work_mess := next_mess;
- next_mess := work_mess^.mess_next;
- next_qe := work_mess^.mess_this;
- WHILE next_qe <> NIL DO
- BEGIN;
-
- {$IFDEF POINT_CHK}
- test_pointer(next_qe);
- {$ENDIF}
-
- work_qe := next_qe;
- next_qe := work_qe^.qe_next;
-
- i := WORD(qe_overhead) + LENGTH(work_qe^.qe_data);
- FREEMEM(work_qe, i);
-
- {$IFDEF FREE_CHK}
- test_free_list;
- {$ENDIF}
-
- END;
-
- DISPOSE(work_mess);
-
- {$IFDEF FREE_CHK}
- test_free_list;
- {$ENDIF}
-
- END;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Reload *)
- (*-----------------------------------------------------------------------*)
-
- message_init(FALSE);
-
- (*-----------------------------------------------------------------------*)
- (* Do a task switch here to allow unblocked tasks to update *)
- (* Also verify time *)
- (*-----------------------------------------------------------------------*)
-
- task_switch;
- time_check;
-
- (*-----------------------------------------------------------------------*)
- (* Release the interrupt lock *)
- (*-----------------------------------------------------------------------*)
-
- free_semaphore(semaphore_interrupts);
-
- (*-----------------------------------------------------------------------*)
- (* Tell user done *)
- (*-----------------------------------------------------------------------*)
-
- window_write(active_tcb^.port_chan_s + '>:', 'Reload is done');
-
- END;
-
- END.